﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ERF;
using Microsoft.Xna.Framework.Graphics;

namespace FirstPerson
{
    /// <summary>
    /// Represents a shader model 2.0 effect that supports light, textures and specular mapping.
    /// </summary>
    public class BasicShaderEffect : EffectBase
    {
        private EffectParameter shaderIndexParameter;
        private EffectParameter specularMapParameter;
        private EffectParameter textureParameter;
        private bool enableTexture;
        private bool enableLight;
        private bool enableSpecularMap;

        /// <summary>
        /// Creates a new instance of the BasicShaderEffect.
        /// </summary>
        /// <param name="game">The game that this instance belongs to.</param>
        public BasicShaderEffect(ERF.ERFGame game)
            : base(game.GraphicsDevice, game.Content.Load<Effect>("Effects\\BasicShader"))
        {
            this.InitParameters();
        }

        /// <summary>
        /// Initializes the parameter fields by fetching the corresponding shader variable parameters.
        /// </summary>
        private void InitParameters()
        {
            this.shaderIndexParameter = this.Parameters["PixelShaderIndex"];
            this.specularMapParameter = this.Parameters["SpecularMap"];
            this.textureParameter = this.Parameters["BasicTexture"];
        }

        /// <summary>
        /// Gets or sets whether to enable texture or not.
        /// </summary>
        public bool EnableTexture
        {
            get
            {
                return this.enableTexture;
            }
            set
            {
                this.enableTexture = value;
                this.UpdateShaderIndex();
            }
        }

        /// <summary>
        /// Gets or sets whether to enable light or not.
        /// </summary>
        public bool EnableLight
        {
            get
            {
                return this.enableLight;
            }
            set
            {
                this.enableLight = value;
                this.UpdateShaderIndex();
            }
        }

        /// <summary>
        /// Gets or sets whether to enable specular mapping or not.
        /// </summary>
        public bool EnableSpecularMap
        {
            get
            {
                return this.enableSpecularMap;
            }
            set
            {
                this.enableSpecularMap = value;
                this.UpdateShaderIndex();
            }
        }

        /// <summary>
        /// Gets or sets the specular map.
        /// </summary>
        public Texture2D SpecularMap
        {
            get
            {
                return this.specularMapParameter.GetValueTexture2D();
            }
            set 
            {
                this.specularMapParameter.SetValue(value);
            }
        }

        /// <summary>
        /// Gets or sets the texture.
        /// </summary>
        public Texture2D Texture
        {
            get
            {
                return this.textureParameter.GetValueTexture2D();
            }
            set
            {
                this.textureParameter.SetValue(value);
            }
        }

        /// <summary>
        /// Updates the index that determines what PixelShader to use.
        /// </summary>
        private void UpdateShaderIndex()
        {
            if (this.enableLight && this.enableTexture)
                if (this.enableSpecularMap)
                    this.shaderIndexParameter.SetValue(4);
                else
                    this.shaderIndexParameter.SetValue(0);
            else if (this.enableLight && !this.enableTexture)
                this.shaderIndexParameter.SetValue(1);
            else if (!this.enableLight && this.enableTexture)
                this.shaderIndexParameter.SetValue(2);
            else
                this.shaderIndexParameter.SetValue(3);

        }

    }
}
